package com.gaofei.acti.controller;

import com.gaofei.acti.domain.ActivitiVo;
import com.gaofei.acti.domain.UserTask;
import com.gaofei.acti.service.LeaveService;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@CrossOrigin
@Slf4j
public class LeaveController {
    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private LeaveService leaveService;


    @Resource
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private RepositoryService repositoryService;

    @RequestMapping("ask4Leave")
    //@RequestBody注解的作用是把前端接受的json格式的对象,转成java对象
    public Object ask4Leave(@RequestBody ActivitiVo vo){
        //1.保存请假的业务数据,到mysql数据库
        leaveService.save(vo);
        System.out.println(vo);
        String bussinessKey = vo.getId()+"";
        //2. 创建一个流程实例(发起请假)
        ProcessInstance processInstance =  runtimeService.startProcessInstanceByKey("qingjia",bussinessKey);
        log.info("流程定义id:{}",processInstance.getProcessDefinitionId());
        log.info("流程实例id:{}",processInstance.getId());
        log.info("当前活动id:{}",processInstance.getActivityId());
        return "success!!";
    }
    /**
     * 查询责任人待办任务
     * @param
     * @return
     */
    @RequestMapping("taskList")
    public Object taskList(@RequestBody ActivitiVo vo){

        List<UserTask> myList = new ArrayList<>(); //由于自带的List<Task>  直接返回前端会报错:ActivitiException: lazy loading outside command context

        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey("qingjia")
                .taskAssignee(vo.getUsername()) //当前登录用户
                .list();

        System.out.println(list);
        //将List<Task> 中的数据,封装到List<UserTask>
        list.forEach(task->{
            UserTask userTask = new UserTask();
            HashMap<String, Object> map = new HashMap<>();
            map.put("id", task.getId());
            map.put("name", task.getName());
            map.put("assignee", task.getAssignee());

            HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
            String businessKey = hpi.getBusinessKey();
            System.out.println(businessKey);//请假表的主键
            ActivitiVo activitiVo1 =  leaveService.findLeaveById(Integer.parseInt(businessKey));
            System.out.println(activitiVo1);
            map.put("cause", activitiVo1.getCause());
            map.put("applyUser", activitiVo1.getUsername());
            map.put("holiday", activitiVo1.getHoliday());
            map.put("processInstanceId", hpi.getId());
            map.put("businessKey", hpi.getBusinessKey());
            userTask.setTask(map);
            myList.add(userTask);
        });

        return myList;
    }
    @RequestMapping("doTask")
    public Object doTask(String taskId,Boolean appro,String taskName){
        HashMap<String, Object> map = new HashMap<>();
        map.put("appro", appro);
        taskService.complete(taskId,map);

        //这行代码走完就是审批通过后
        //怎么判断是人事审批,和部门领导审批呢?
        if("人事审批".equals(taskName)){
            //发送kafka消息了
            log.info("开始发送kafka消息");
        }
        log.info("任务处理完成:{}",taskId);
        return "success";
    }


    @RequestMapping("viewTask")
    public void viewTask(String processInstanceId , HttpServletResponse response) throws IOException, TranscoderException {
        InputStream in = this.getProcessDiagram(processInstanceId);

        //svg 转  png
        byte[] streamBytes = IOUtils.toByteArray(in);
        ByteArrayOutputStream byteArrayOutputStream = svgToPng(streamBytes);
        String imageName = "image" + Instant.now().getEpochSecond() + ".png";
//        byteArrayOutputStream.writeTo(new FileOutputStream(new File("D:/images/"+imageName)));
//        FileInputStream fis = new FileInputStream(new File("D:/images/" + imageName));
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());

        response.setContentType("text/html; charset=UTF-8");
        response.setContentType("image/png");
        response.addHeader("Content-Disposition", "inline; filename=" + imageName);
        ServletOutputStream outputStream = response.getOutputStream();
        IOUtils.copy(byteArrayInputStream, outputStream);
        outputStream.close();
    }


    private ByteArrayOutputStream svgToPng(byte[] streamBytes) throws TranscoderException, IOException {

        PNGTranscoder t = new PNGTranscoder();

        TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(streamBytes));

        ByteArrayOutputStream ostream = new ByteArrayOutputStream();

        TranscoderOutput output = new TranscoderOutput(ostream);

        t.transcode(input, output);

        ostream.flush();
        return ostream;

    }

    /**
     * Get Process instance diagram
     */
    public InputStream getProcessDiagram(String processInstanceId) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();

        List<String> highLightedActivities = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list().stream().map(item -> item.getActivityId()).collect(Collectors.toList());

        // null check
        if (processInstance != null) {
            // get process model
            BpmnModel model = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
            if (model != null && model.getLocationMap().size() > 0) {
                ProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
                // 生成流程图 已启动的task 高亮
                return generator.generateDiagram(model,
                        runtimeService.getActiveActivityIds(processInstanceId), highLightedActivities, "simsun", "simsun", "simsun");
                // 生成流程图 都不高亮
//                return generator.generateDiagram(model,Collections.<String>emptyList());
            }
        }
        return null;
    }

}
